<template>
  <div class="model-evaluation">
    <div class="page-header">
      <h1>模型评估</h1>
    </div>
    
    <el-row :gutter="20" class="mb-4">
      <el-col :span="24">
        <el-card shadow="hover">
          <template #header>
            <div class="card-header">
              <span>选择模型</span>
            </div>
          </template>
          
          <el-form :inline="true" :model="evaluationForm" class="demo-form-inline">
            <el-form-item label="模型选择">
              <el-select v-model="evaluationForm.modelId" placeholder="请选择模型" style="width: 250px">
                <el-option
                  v-for="model in modelList"
                  :key="model.id"
                  :label="`${model.name} (${model.type})`"
                  :value="model.id"
                />
              </el-select>
            </el-form-item>
            
            <el-form-item label="测试数据">
              <el-select v-model="evaluationForm.testData" placeholder="请选择测试数据" style="width: 250px">
                <el-option label="默认测试集" value="default_test" />
                <el-option label="新客户数据" value="new_customers" />
                <el-option label="特定时间段数据" value="time_period" />
              </el-select>
            </el-form-item>
            
            <el-form-item>
              <el-button type="primary" @click="evaluateModel" :loading="isEvaluating">评估模型</el-button>
            </el-form-item>
          </el-form>
        </el-card>
      </el-col>
    </el-row>
    
    <el-row :gutter="20" v-if="evaluationResult" class="mb-4">
      <el-col :span="24">
        <el-card shadow="hover">
          <template #header>
            <div class="card-header">
              <span>评估结果</span>
              <el-button type="primary" size="small">导出报告</el-button>
            </div>
          </template>
          
          <el-row :gutter="20">
            <el-col :span="8">
              <div class="metric-card">
                <div class="metric-title">准确率</div>
                <div class="metric-value">{{ evaluationResult.accuracy }}%</div>
                <el-progress :percentage="evaluationResult.accuracy" :color="getColorForMetric(evaluationResult.accuracy)"></el-progress>
              </div>
            </el-col>
            
            <el-col :span="8">
              <div class="metric-card">
                <div class="metric-title">精确率</div>
                <div class="metric-value">{{ evaluationResult.precision }}%</div>
                <el-progress :percentage="evaluationResult.precision" :color="getColorForMetric(evaluationResult.precision)"></el-progress>
              </div>
            </el-col>
            
            <el-col :span="8">
              <div class="metric-card">
                <div class="metric-title">召回率</div>
                <div class="metric-value">{{ evaluationResult.recall }}%</div>
                <el-progress :percentage="evaluationResult.recall" :color="getColorForMetric(evaluationResult.recall)"></el-progress>
              </div>
            </el-col>
          </el-row>
          
          <el-row :gutter="20" class="mt-4">
            <el-col :span="8">
              <div class="metric-card">
                <div class="metric-title">F1分数</div>
                <div class="metric-value">{{ evaluationResult.f1Score }}</div>
                <el-progress :percentage="evaluationResult.f1Score * 100" :color="getColorForMetric(evaluationResult.f1Score * 100)"></el-progress>
              </div>
            </el-col>
            
            <el-col :span="8">
              <div class="metric-card">
                <div class="metric-title">AUC</div>
                <div class="metric-value">{{ evaluationResult.auc }}</div>
                <el-progress :percentage="evaluationResult.auc * 100" :color="getColorForMetric(evaluationResult.auc * 100)"></el-progress>
              </div>
            </el-col>
            
            <el-col :span="8">
              <div class="metric-card">
                <div class="metric-title">阈值</div>
                <div class="metric-value">{{ evaluationResult.threshold }}</div>
                <el-slider v-model="evaluationResult.threshold" :min="0" :max="1" :step="0.01" disabled show-input></el-slider>
              </div>
            </el-col>
          </el-row>
        </el-card>
      </el-col>
    </el-row>
    
    <el-row :gutter="20" v-if="evaluationResult">
      <el-col :xs="24" :lg="12" class="mb-xs-4">
        <el-card shadow="hover" class="chart-card">
          <template #header>
            <div class="card-header">
              <span>混淆矩阵</span>
            </div>
          </template>
          <div class="confusion-matrix">
            <div class="cm-row">
              <div class="cm-header"></div>
              <div class="cm-header">预测: 不流失</div>
              <div class="cm-header">预测: 流失</div>
            </div>
            <div class="cm-row">
              <div class="cm-header">实际: 不流失</div>
              <div class="cm-cell cm-tn">{{ evaluationResult.confusionMatrix.tn }}</div>
              <div class="cm-cell cm-fp">{{ evaluationResult.confusionMatrix.fp }}</div>
            </div>
            <div class="cm-row">
              <div class="cm-header">实际: 流失</div>
              <div class="cm-cell cm-fn">{{ evaluationResult.confusionMatrix.fn }}</div>
              <div class="cm-cell cm-tp">{{ evaluationResult.confusionMatrix.tp }}</div>
            </div>
          </div>
        </el-card>
      </el-col>
      
      <el-col :xs="24" :lg="12">
        <el-card shadow="hover" class="chart-card">
          <template #header>
            <div class="card-header">
              <span>ROC曲线</span>
            </div>
          </template>
          <div class="chart-placeholder">
            <!-- 这里放ROC曲线图表，实际项目中可以使用ECharts实现 -->
            <div class="chart-text">ROC曲线 (AUC = {{ evaluationResult.auc }})</div>
          </div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script setup name="ModelEvaluation">
import { ref, reactive } from 'vue'

// 评估表单
const evaluationForm = reactive({
  modelId: '',
  testData: 'default_test'
})

// 状态
const isEvaluating = ref(false)
const evaluationResult = ref(null)

// 模拟模型列表
const modelList = [
  { id: 1, name: 'StackingEnsemble', type: '集成模型' },
  { id: 2, name: 'RandomForest', type: '随机森林' },
  { id: 3, name: 'XGBoost', type: '梯度提升树' },
  { id: 4, name: 'LogisticRegression', type: '逻辑回归' }
]

// 评估模型
const evaluateModel = () => {
  if (!evaluationForm.modelId) {
    // 提示用户选择模型
    return
  }
  
  isEvaluating.value = true
  
  // 模拟评估过程
  setTimeout(() => {
    const selectedModel = modelList.find(model => model.id === evaluationForm.modelId)
    
    // 生成模拟评估结果
    evaluationResult.value = {
      modelName: selectedModel.name,
      modelType: selectedModel.type,
      accuracy: 87.5,
      precision: 88.2,
      recall: 86.9,
      f1Score: 0.876,
      auc: 0.921,
      threshold: 0.45,
      confusionMatrix: {
        tp: 157,
        tn: 1403,
        fp: 21,
        fn: 24
      }
    }
    
    isEvaluating.value = false
  }, 1000)
}

// 根据指标值获取颜色
const getColorForMetric = (value) => {
  if (value >= 90) return '#67C23A' // 绿色
  if (value >= 80) return '#409EFF' // 蓝色
  if (value >= 70) return '#E6A23C' // 黄色
  return '#F56C6C' // 红色
}
</script>

<style lang="scss" scoped>
.model-evaluation {
  padding: 20px;
  
  .page-header {
    margin-bottom: 20px;
    
    h1 {
      font-size: 22px;
      font-weight: 500;
      margin: 0;
    }
  }
  
  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  
  .mb-4 {
    margin-bottom: 20px;
  }
  
  .mt-4 {
    margin-top: 20px;
  }
  
  .mb-xs-4 {
    @media (max-width: 992px) {
      margin-bottom: 20px;
    }
  }
  
  .chart-card {
    height: 100%;
  }
  
  .metric-card {
    background-color: #f8f8f8;
    border-radius: 8px;
    padding: 15px;
    text-align: center;
    
    .metric-title {
      font-size: 16px;
      color: #606266;
      margin-bottom: 5px;
    }
    
    .metric-value {
      font-size: 24px;
      font-weight: bold;
      margin-bottom: 10px;
    }
  }
  
  .confusion-matrix {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-top: 10px;
    
    .cm-row {
      display: flex;
      width: 100%;
      
      .cm-header {
        flex: 1;
        padding: 10px;
        text-align: center;
        font-weight: 500;
        background-color: #f5f7fa;
      }
      
      .cm-cell {
        flex: 1;
        padding: 20px;
        text-align: center;
        font-size: 18px;
        font-weight: 500;
      }
      
      .cm-tn {
        background-color: #ecf5ff;
        color: #409EFF;
      }
      
      .cm-fp {
        background-color: #fef0f0;
        color: #F56C6C;
      }
      
      .cm-fn {
        background-color: #fdf6ec;
        color: #E6A23C;
      }
      
      .cm-tp {
        background-color: #f0f9eb;
        color: #67C23A;
      }
    }
  }
  
  .chart-placeholder {
    height: 300px;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: #f8f8f8;
    border-radius: 4px;
    
    .chart-text {
      font-size: 18px;
      color: #909399;
    }
  }
}
</style> 